﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
 * 创建者：zhaijc
 * 创建时间：2023/4/14 11:15:57
 * 版本：V1.0.0
 * 描述：
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 注 释 >>

using DotNetty.Buffers;
using DotNetty.Codecs;
using DotNetty.Transport.Channels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MedianSocketService.netty.MedianProtocol
{
    public class MedianProtocolDecoder : ByteToMessageDecoder
    {
        // 包头长度
        private const int HeaderLength = 13;
        // 包尾长度
        private const int FooterLength = 2;
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List<object> output)
        {
            try
            {
                while (true)
                {
                    // 标记当前读取位置
                    input.MarkReaderIndex();
                    // 可读取的字节数
                    int readableBytes = input.ReadableBytes;
                    // 如果数据不足一个完整的包头，直接返回
                    if (readableBytes < HeaderLength + FooterLength)
                    {
                        break;
                    }
                    // 读取包头
                    byte[] header = new byte[HeaderLength];
                    input.ReadBytes(header);

                    // 检查包头是否合法
                    if (!IsValidHeader(header))
                    {
                        // 恢复之前的读取位置
                        input.ResetReaderIndex();
                        input.ReadByte();
                        continue;
                    }
                    // 读取包体+包尾长度
                    int bodyLength = header[11] + (header[12] << 8);
                    // 如果可读取的字节数小于数据体长度加包尾长度，说明数据不足一个完整的包，直接返回
                    if (readableBytes < HeaderLength + bodyLength)
                    {
                        // 恢复之前的读取位置
                        input.ResetReaderIndex();
                        return;
                    }
                    // 读取包体+包尾
                    byte[] bodyAndTail = new byte[bodyLength];
                    input.ReadBytes(bodyAndTail);

                    // 将解码后的消息添加到 output 列表中，交给后面的处理器进行处理
                    output.Add(header.Concat(bodyAndTail).ToArray());
                }

            }
            catch (Exception ex)
            {
                // 发生异常时，抛出 CorruptedFrameException 异常，表示解码出错
                throw new CorruptedFrameException("Decode error!");
            }

        }

        // 检查包头是否合法
        private bool IsValidHeader(byte[] header)
        {
            if (header.Length != HeaderLength)
            {
                return false;
            }

            return header[0] == 0xAC && header[1] == 0xFD && header[2] == 0xFD && header[3] == 0xAC;
        }

        // 检查包尾是否合法
        private bool IsValidFooter(byte[] footer)
        {
            if (footer.Length != FooterLength)
            {
                return false;
            }

            return footer[0] == 0xFE && footer[1] == 0xFE;
        }

    }
}
